package com.lxd.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

import javax.annotation.Resource;

import com.lxd.entity.LoginRequest;
import com.lxd.entity.RegisterRequest;
import com.lxd.entity.TokenUserInfoDto;
import com.lxd.entity.UserRequest;
import com.lxd.entity.enums.ResponseCodeEnum;
import com.lxd.entity.po.*;
import com.lxd.entity.query.*;
import com.lxd.exception.BusinessException;
import com.lxd.mappers.*;
import com.lxd.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lxd.entity.enums.PageSize;
import com.lxd.entity.vo.PaginationResultVO;
import com.lxd.service.UserService;
import com.lxd.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;


/**
 * 业务接口实现
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper<User, UserQuery> userMapper;
    @Autowired
    private RedisUtil redis;
    @Resource
    private MemberMapper<Member, MemberQuery> memberMapper;
    @Resource
    private ClubMapper<Club, ClubQuery> clubMapper;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<User> findListByParam(UserQuery param) {
        return this.userMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(UserQuery param) {
        return this.userMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<User> findListByPage(UserQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<User> list = this.findListByParam(param);
        PaginationResultVO<User> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(User bean) {
        return this.userMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<User> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.userMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<User> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.userMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(User bean, UserQuery param) {
        StringTools.checkParam(param);
        return this.userMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(UserQuery param) {
        StringTools.checkParam(param);
        return this.userMapper.deleteByParam(param);
    }

    /**
     * 根据UserId获取对象
     */
    @Override
    public User getUserByUserId(Long userId) {
        return this.userMapper.selectByUserId(userId);
    }

    /**
     * 根据UserId修改
     */
    @Override
    public Integer updateUserByUserId(User bean, Long userId) {
        return this.userMapper.updateByUserId(bean, userId);
    }

    /**
     * 根据UserId删除
     */
    @Override
    public Integer deleteUserByUserId(Long userId) {
        return this.userMapper.deleteByUserId(userId);
    }

    /**
     * 根据UserName获取对象
     */
    @Override
    public User getUserByUserName(String userName) {
        return this.userMapper.selectByUserName(userName);
    }

    /**
     * 根据UserName修改
     */
    @Override
    public Integer updateUserByUserName(User bean, String userName) {
        return this.userMapper.updateByUserName(bean, userName);
    }

    /**
     * 根据UserName删除
     */
    @Override
    public Integer deleteUserByUserName(String userName) {
        return this.userMapper.deleteByUserName(userName);
    }

    @Override
    public void register(RegisterRequest registerRequest) {

        User u = userMapper.selectByEmail(registerRequest.getEmail());
        if (u != null) {
            throw new RuntimeException("邮箱已经被注册！！！");
        }
        User user = new User();
        Date now = new Date();
        user.setUserName(registerRequest.getUsername());
        user.setPassword(registerRequest.getPassword());
        user.setUserRealName(registerRequest.getRealName());
        user.setRole("学生");//默认学生
        user.setEmail(registerRequest.getEmail());
        user.setCreatedAt(now);
        user.setUpdatedAt(now);

        Integer i = userMapper.insert(user);
        if (i.equals("0")) {
            throw new BusinessException("注册失败！！！");
        }


    }

    @Override
    public TokenUserInfoDto login(LoginRequest loginRequest) {
        //校验用户，密码
        User user = userMapper.selectByEmail(loginRequest.getEmail());
        if (user == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_902);
        }
        if (!user.getPassword().equals(loginRequest.getPassword())) {
            throw new BusinessException(ResponseCodeEnum.CODE_903);
        }
        //生成token体
        String token = user.getUserId() + UUID.randomUUID().toString();
        TokenUserInfoDto tokenUserInfoDto = new TokenUserInfoDto();
        tokenUserInfoDto.setUserId(user.getUserId().toString());
        tokenUserInfoDto.setUserName(user.getUserName());
        tokenUserInfoDto.setEmail(user.getEmail());
        tokenUserInfoDto.setAdmin(user.getRole().equals("管理员"));
        tokenUserInfoDto.setToken(token);
        tokenUserInfoDto.setUserRealName(user.getUserRealName());
        tokenUserInfoDto.setCreatedAt(user.getCreatedAt());//注册时间

        // 存储到redis中
        // key：token value：tokenInfoDto
        redis.set(token, tokenUserInfoDto, 1, TimeUnit.DAYS);

        // 存储到redis中 key：USER  key:userid value：user
        redis.setHash("USER",user.getUserId().toString(),user);

        return tokenUserInfoDto;

    }

    @Override
    public void setPresident(UserRequest userRequest) {
        Long userId = userRequest.getUserId();
        Long clubId = Long.valueOf(userRequest.getClubId());

        // 先检查该社团是否已有社长
        MemberQuery memberQuery = new MemberQuery();
        memberQuery.setClubId(clubId);
        memberQuery.setRole("社长");

        List<Member> members = memberMapper.selectList(memberQuery);
        if (!members.isEmpty()) {
            for (Member member : members) {
                if (member.getUserId().equals(userId)) {
                    throw new BusinessException("该用户已经是该社团团长了！！！");
                }
            }
            throw new BusinessException("该社团已有社长！！！");
        }

        // 更新用户角色为社长
        Member member = new Member();
        member.setUserId(userId);
        member.setClubId(clubId);
        member.setRole("社长");
        member.setJoinedAt(new Date());
        memberMapper.insert(member);
    }

    @Override
    @Transactional
    public void deleteUser(UserRequest userRequest) {
        Long userId = userRequest.getUserId();
        User user1 = userMapper.selectByUserId(userId);
        if (user1.getRole().equals("管理员")) {
            throw new BusinessException("管理员无法注销！！！");
        }
        User user = new User();
        user.setUserId(userId);
        user.setUserName("该用户已注销");
        user.setUserRealName(userRequest.getUserRealName() + "(已注销)");

        MemberQuery memberQuery = new MemberQuery();
        memberQuery.setUserId(userId);
        memberQuery.setRole("社长");
        List<Member> members = memberMapper.selectList(memberQuery);
        for (Member member : members) {
            ClubQuery clubQuery = new ClubQuery();
            clubQuery.setId(member.getClubId());
            Club club = clubMapper.select(clubQuery);
            throw new BusinessException("该用户是社团" + club.getName() + "的社长，无法注销！！！");
        }

        userMapper.updateByUserId(user, userId);
    }

    @Resource
    private RegistrationMapper<Registration, RegistrationQuery> registrationMapper;
    @Resource
    private ActivityMapper<Activity, ActivityQuery> activityMapper;

    @Override
    public Map<String, Object> getUserInfo(String token) {
        // 从redis中获取用户信息
        TokenUserInfoDto userInfo = (TokenUserInfoDto) redis.get(token);
        if (userInfo == null) {
            throw new BusinessException("登录已过期，请重新登录");
        }

        Map<String, Object> result = new HashMap<>();

        // 基本信息
        result.put("email", userInfo.getEmail());
        result.put("userName", userInfo.getUserName());
        result.put("userRealName", userInfo.getUserRealName());
        //显示注册时间
        result.put("registerTime:", userInfo.getCreatedAt());

        //查询用户申请历史
        RegistrationQuery registrationQuery = new RegistrationQuery();
        registrationQuery.setUserId(Long.valueOf(userInfo.getUserId()));
        List<Registration> registrations = registrationMapper.selectList(registrationQuery);

        List<Map<String, Object>> activityHistory = new ArrayList<>();
        List<Map<String, Object>> clubHistory = new ArrayList<>();
        for (Registration registration : registrations) {// 获取用户活动经历
            if (registration.getActivityId() != null) {
                Activity activity = activityMapper.selectById(registration.getActivityId());
                Map<String, Object> act = new HashMap<>();
                act.put("activityName", activity.getTitle());
                act.put("startTime", activity.getStartTime());
                act.put("endTime", activity.getEndTime());

                //设置活动状态
                Date date = new Date();
                if (date.after(activity.getEndTime())) {
                    act.put("status", "已结束");
                } else if (date.before(activity.getStartTime())) {
                    act.put("status", "未开始");
                } else {
                    act.put("status", "进行中");
                }
                activityHistory.add(act);
            } else if (registration.getClubId() != null) {// 获取用户社团经历
                Map<String, Object> club = new HashMap<>();
                // 获取社团信息
                Club clubInfo = clubMapper.selectById(registration.getClubId());
                club.put("clubName", clubInfo.getName());

                if (registration.getStatus() == 1) {
                    club.put("status", "已加入");
                } else if (registration.getStatus() == 2) {
                    club.put("status", "已拒绝");
                    club.put("rejectTime", registration.getUpdatedAt());
                } else if (registration.getStatus() == 0) {
                    club.put("status", "待处理");
                }
                clubHistory.add(club);
            }

        }
        result.put("clubHistory", clubHistory);
        result.put("activityHistory", activityHistory);

        return result;
    }

    @Override
    public void cancelPresident(UserRequest userRequest) {
        Long userId = userRequest.getUserId();
        User user = userMapper.selectByUserId(userId);

        // 检查用户是否是管理员
        if (!user.getRole().equals("管理员")) {
            throw new BusinessException("该用户不是管理员！");
        }
        // 更新用户角色为普通学生
        User updateUser = new User();
        updateUser.setUserId(userId);
        updateUser.setRole("学生");
        userMapper.updateByUserId(updateUser, userId);
    }

    @Override
    public Integer getTotalCount() {
        return userMapper.selectCount(new UserQuery());
    }

}